package com.canto.access.config;

import com.canto.access.services.DynamicSecurityService;
import com.canto.wanna.user.pojo.doo.ResourceDO;
import com.canto.wanna.user.pojo.query.ResourceQuery;
import com.canto.wanna.user.pojo.query.UserQuery;
import com.canto.wanna.user.services.ResourceService;
import com.canto.wanna.user.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Canto权限配置
 *
 * @author jsryin
 * @version 2021-07-05
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class CantoSecurityConfig extends SecurityConfig {

    @Autowired
    private UserService userService;
    @Autowired
    private ResourceService resourceService;

    @Bean
    public UserDetailsService userDetailsService() {
        return loginName -> {
            UserQuery userQuery = new UserQuery();
            userQuery.setLoginName(loginName);
            UserDetails userDetails = (UserDetails) userService.loadUserByUsername(userQuery);
            return userDetails;
        };
    }

    @Bean
    public DynamicSecurityService dynamicSecurityService() {
        return new DynamicSecurityService() {
            @Override
            public Map<String, ConfigAttribute> loadDataSource() {
                //获取url对应权限标识
                List<ResourceDO> resourceDOList = resourceService.findList(new ResourceQuery());
                Map<String, ConfigAttribute> map = new ConcurrentHashMap<>();
                for (ResourceDO resourceDO : resourceDOList) {
                    map.put(resourceDO.getUrl(), new org.springframework.security.access.SecurityConfig(resourceDO.getAuthority()));
                }
                return map;
            }
        };
    }

}
